package com.szwistar.common.jnlua;

import com.naef.jnlua.LuaState;
import com.naef.jnlua.NamedJavaFunction;

public class LuaBinary {
	private static final String PACKAGE = "binary";
	static LuaBinary INSTANCE;

	private LuaBinary() {}

	public static LuaBinary instance() {
		if( INSTANCE == null ) {
			INSTANCE = new LuaBinary();
		}
		return INSTANCE;
	}

	/**
	 * 将一个整数按位取反
	 * binary.bnot(3) -------->-4
	 */
	protected static class JLFunc_bnot implements NamedJavaFunction {
        @Override
        public String getName() { return "bnot"; }

        @Override
        public int invoke(LuaState luaState) {
            int arg = luaState.checkInteger(1);
            luaState.pushInteger(~arg);
            return 1;
        }
    }

	/**
	 * 将一个byte数组(lua中用string表示)按字节取反
	 * binary.bnot(3) -------->-4
	 */
	protected static class JLFunc_byteArrayNot implements NamedJavaFunction {
        @Override
        public String getName() {
            return "byteArrayNot";
        }

        @Override
        public int invoke(LuaState luaState) {
            byte[] arg = luaState.checkByteArray(1);
            for( int i=0; i<arg.length; i++ ) {
            	if( arg[i] == 0 ) {
            		arg[i] = 1;
            	} else {
            		arg[i] = 0;
            	}
            }
            luaState.pushString(new String(arg));
            return 1;
        }
    }

	/**
	 * 将一个整数转换成二进制表示的字符串
	 * binary.toBitStr(3) ------------>\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\1
	 */
	protected static class JLFunc_toBitStr implements NamedJavaFunction {
        @Override
        public String getName() {
            return "toBitStr";
        }

        @Override
        public int invoke(LuaState luaState) {
            int value = luaState.checkInteger(1);
            byte[] src = new byte[4];
            src[3] =  (byte) ((value>>24) & 0xFF);
            src[2] =  (byte) ((value>>16) & 0xFF);
            src[1] =  (byte) ((value>>8) & 0xFF);
            src[0] =  (byte) (value & 0xFF);
            luaState.pushString(new String(src));
            return 1;
        }
    }

	public boolean init(LuaState luaState) {
		// Register lua functions
        NamedJavaFunction[] luaFunctions = new NamedJavaFunction[] {
            new JLFunc_bnot(),
            new JLFunc_byteArrayNot(),
            new JLFunc_toBitStr(),
        };

        luaState.register(PACKAGE, luaFunctions);
        luaState.pop(1);
        return true;
	}
}
